package me.zhengjie.modules.weixin.service.impl;

import cn.hutool.core.thread.ThreadUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.vioao.wechat.api.UserApi;
import com.github.vioao.wechat.bean.response.user.UserResponse;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.bean.WxOAuth2UserInfo;
import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import me.zhengjie.config.exception.WeChatException;
import me.zhengjie.constant.ConstantUtils;
import me.zhengjie.modules.system.domain.DisLockUser;
import me.zhengjie.modules.system.domain.WxUser;
import me.zhengjie.modules.system.service.WxUserService;
import me.zhengjie.modules.web.service.impl.AtmrOrderServiceImpl;
import me.zhengjie.modules.web.service.mybatisplus.IDisLockUserPlusService;
import me.zhengjie.modules.weixin.service.IWechatOAuthService;
import me.zhengjie.modules.weixin.utils.DateUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.List;
import java.util.Objects;

@Service
public class WechatOAuthServiceImpl implements IWechatOAuthService {

    private static final Logger log = LoggerFactory.getLogger(WechatOAuthServiceImpl.class);

    @Autowired
    private WxMpService wxMpService;

    @Autowired
    private WxUserService wxUserService;

    @Autowired
    private IDisLockUserPlusService disLockUserPlusService;

    @Override
    public String getOAuthUrl(String url, String scope, String state) throws WeChatException {

        if (StringUtils.isBlank(scope)) {
            scope = WxConsts.OAuth2Scope.SNSAPI_USERINFO;
        }
        return wxMpService.getOAuth2Service().buildAuthorizationUrl(url, scope, state);
    }

    @Override
    public WxOAuth2UserInfo getWxUserInfo(String code) throws WeChatException {
        try {
            WxOAuth2AccessToken wxMpOAuth2AccessToken = wxMpService.getOAuth2Service().getAccessToken(code);
            log.info("wxMpOAuth2AccessToken=" + JSON.toJSONString(wxMpOAuth2AccessToken));
            WxOAuth2UserInfo wxMpUser = wxMpService.getOAuth2Service().getUserInfo(wxMpOAuth2AccessToken, "zh_CN");
            log.info("wxMpUser=" + JSON.toJSONString(wxMpUser));
            if (Objects.isNull(wxMpUser) || StringUtils.isBlank(wxMpUser.getOpenid())) {
                return wxMpUser;
            }
            ThreadUtil.execAsync(() -> {
                WxUser wxUser = wxUserService.findByOpenId(wxMpUser.getOpenid());
                if (Objects.isNull(wxUser)) {
                    WxUser user = new WxUser();
                    user.setNickname(wxMpUser.getNickname());
                    user.setHeadimgurl(wxMpUser.getHeadImgUrl());
                    user.setSubscribe(Boolean.FALSE.toString());
                    user.setSubscribeTime(DateUtil.date2String(new Date()));
                    user.setOpenId(wxMpUser.getOpenid());
                    user.setRemark("授权插入");
                    UserResponse wxUser1 = getWxUser(wxMpUser.getOpenid());
                    if (null != wxUser1) {
                        user.setProvince(wxUser1.getProvince());
                        user.setCity(wxUser1.getCity());
                        user.setSex(String.valueOf(wxUser1.getSex()));
                        user.setCountry(wxUser1.getCountry());
                        user.setGroupid(String.valueOf(wxUser1.getGroupid()));
                        user.setLanguage(wxUser1.getLanguage());
                    }
                    LambdaQueryWrapper<DisLockUser> wrapper = new LambdaQueryWrapper<>();
                    wrapper.eq(DisLockUser::getLockStatus, ConstantUtils.Valid);
                    List<DisLockUser> lockUserTime = disLockUserPlusService.list(wrapper);
                    String lockTime = "";
                    if (CollectionUtils.isEmpty(lockUserTime)) {
                        lockTime = String.valueOf(ConstantUtils.LockUserDefaultMonth);
                    } else {
                        lockTime = String.valueOf(lockUserTime.get(0).getLockMonth());
                    }
                    Date date = me.zhengjie.utils.DateUtil.addMonth(new Date(), Integer.parseInt(lockTime));
                    user.setLockTime(me.zhengjie.utils.DateUtil.dateConvertTimestamp(date));
                    wxUserService.create(user);
                }else {
                    if (StringUtils.isNotBlank(wxUser.getNickname()) || StringUtils.isNotBlank(wxUser.getHeadimgurl())){
                        wxUser.setNickname(wxMpUser.getNickname());
                        wxUser.setHeadimgurl(wxMpUser.getHeadImgUrl());
                        wxUserService.update(wxUser);
                    }
                }
            });
            return wxMpUser;
        } catch (WxErrorException e) {
            log.error("根据code获取用户信息异常", e);
        }
        return null;
    }

    @Override
    public String authorize(String code, Long auId) throws WeChatException {
        return null;
    }

    @Override
    public String generate(String scene) throws WeChatException {
        try {
            WxMpQrCodeTicket wxMpQrCodeTicket = wxMpService.getQrcodeService().qrCodeCreateLastTicket(scene);
            if (null != wxMpQrCodeTicket && StringUtils.isNotBlank(wxMpQrCodeTicket.getTicket())) {
                return wxMpService.getQrcodeService().qrCodePictureUrl(wxMpQrCodeTicket.getTicket());
            }
        } catch (WxErrorException e) {
            log.error("生成二维码异常", e);
        }
        return null;
    }

    @Override
    public String getMobile(String code, String encryptedData, String iv) {
        return null;
    }

    private UserResponse getWxUser(String openId) {
        try {
            UserResponse userInfo = UserApi.getUserInfo(wxMpService.getAccessToken(), openId);
            if (null != userInfo) {
                return userInfo;
            }
        } catch (WxErrorException e) {
            log.error("getUserInfo is error", e);
        }
        WxMpUser wxMpUser = null;
        try {
            wxMpUser = wxMpService.getUserService().userInfo(openId);
        } catch (WxErrorException e) {
            log.error("userInfo is error", e);
        }
        if (wxMpUser != null) {
            UserResponse response = new UserResponse();
            response.setNickname(wxMpUser.getNickname());
            response.setHeadimgurl(wxMpUser.getHeadImgUrl());
            response.setSex(0);
            return response;
        }
        return null;
    }
}
